<?php
// +----------------------------------------------------------------------
// | Yzncms [ 御宅男工作室 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2018 http://yzncms.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 御宅男 <530765310@qq.com>
// +----------------------------------------------------------------------

// +----------------------------------------------------------------------
// | 地区模型
// +----------------------------------------------------------------------
namespace app\api\model;

use app\admin\model\VipCard;
use app\admin\model\VipPrice;
use app\api\controller\PayCall;
use think\Db;
use think\Exception;
use think\Model;
use EasyWeChat\Factory;

use function form\e;

class Pay extends ApiModel
{


    protected $vip_type = [1 => '月', 2 => '季', '3' => '年', '4' => '终身'];
    protected $vip_group = [1 => '1类会员', 2 => '2类会员', 3 => '3类会员', 4 => '4类会员'];

    public function PaySpecial($params = array())
    {
        $order_id = $params['order_id'] ?? 0;
        $isWmini = $params['is_wmini'] ?? 0;
        if (!$order_id) {
            $area_name = $params['area_name'] ?? '';
            $special_id = $params['special_id'] ?? 0;
            $member_id = $params['uid'] ?? 1;
            $special = (new SpecialModel())->where(['id' => $special_id, 'status' => 1])->find();

            if (!$special) {
                return $this->api_error('数据不存在');
            }
            //获取专项分类
            $specialCate = (new SpecialCateModel())->where(['id' => $special['account_cate_id']])->find();
            if (!$specialCate) {
                return $this->api_error('数据不存在');
            }
            //获取用户信息
            $member = (new MemberModel())->where(['id' => $member_id])->find();
            if (!$member) {
                return $this->api_error('您还没有登陆～');
            }
            $pay_amount = $special['default_price'];
            //根据地域查询价格
            $area_price = (new AreaPrice())->where(['area_name' => $area_name, 'special_id' => $special_id])->find();
            if ($area_price) {
                $pay_amount = $area_price['price'];
            }
            $amount = $pay_amount;
            $out_trade_no = $this->build_order_no("SPEC");
            $pay_amount = $this->userVipPayment($member, $amount);
            if ($pay_amount < 0.01) {
                return $this->api_error('付费金额，必须大于0.01');
            }
            if (!$isWmini) {
                if ($pay_amount > $member['wallet']) {
                    return $this->api_error('余额不足');
                }
                try {
                    Db::startTrans();
                    $this->createSpecialOrder(
                        $special,
                        $pay_amount,
                        $amount,
                        $member,
                        $specialCate,
                        $out_trade_no,
                        $area_name,
                        $isWmini,
                        1
                    );
                    //扣除余额
                    (new MemberModel())->where(['id' => $member_id])->setDec('wallet', $pay_amount);
                    //添加日志
                    (new VipCardBill())->addBill($member_id, "购买" . $special['name'], 2, $pay_amount);
                    //执行分销
                    (new PayCall())->retail($out_trade_no,$member_id,$pay_amount,'spec');
                    Db::commit();
                    return $this->api_success('下单成功', true);
                } catch (\Exception $e) {
                    Db::rollback();
                    return $this->api_error('下单失败～');
                }
            } else {
                //生成订单
                if (!$this->createSpecialOrder(
                    $special,
                    $pay_amount,
                    $amount,
                    $member,
                    $specialCate,
                    $out_trade_no,
                    $area_name,
                    $isWmini
                )) {
                    return $this->api_error('下单失败');
                }
            }
        } else {
            //再次支付
            $order = (new SpecialOrder())->where(['out_trade_no' => $order_id])->find();
            if ($order['status'] != 0) {
                return $this->api_error('该订单已支付');
            }
            $special = (new SpecialModel())->where(['id' => $order['special_id'], 'status' => 1])->find();
            if (!$special) {
                return $this->api_error('数据不存在');
            }
            //获取用户信息
            $member = (new MemberModel())->where(['id' => $order['member_id']])->find();
            if (!$member) {
                return $this->api_error('您还没有登陆～');
            }
            $out_trade_no = $order['out_trade_no'];
            $pay_amount = $order['pay_amount'];
        }

        $config = $this->toPay($special['name'], $out_trade_no, $pay_amount, 'specialCallback', $member['openid']);
        if ($config) {
            return $this->api_success('获取成功', $config);
        } else {
            return $this->api_error('下单失败');
        }
    }


    public function userVipPayment($member, $amount)
    {
        //查询是否是会员
        if ($member['vip_type'] > 0 && $member['vip_expire_time'] > time()) {
            //查询vip_id
            $vip = (new VipCard())->where(['id' => $member['vip_type']])->find();
            if ($vip) {
                $amount = $amount * $vip['discount'] / 10;
            }
        }

        return $amount;
    }


    //购买企服套餐
    public function PayPackage($params = array())
    {
        $order_id = $params['order_id'] ?? 0;
        if (!$order_id) {
            $area_name = $params['area_name'] ?? '';
            $package_id = $params['package_id'] ?? 0;
            $member_id = $params['uid'] ?? 1;
            $spec_id = $params['spec_id'] ?? 0;
            $realname = $params['realname'] ?? '';
            $phone = $params['phone'] ?? '';
            $notes = $params['notes'] ?? '';
            $isWmini = $params['is_wmini'] ?? 0;

            if (!$realname || !$phone) {
                return $this->api_error('请填写联系方式');
            }

            //查询套餐ID
            $package = (new CompanyPackageModel())->where(['id' => $package_id, 'status' => 1])->find();
            if (!$package) {
                return $this->api_error('企业服务套餐不存在');
            }
            //查询是否在特殊地区呢
            $company_area_sepc = (new CompanyPriceModel())->where(
                ['company_package_id' => $package_id, 'spec_id' => $spec_id]
            )->find();

            //获取用户信息
            $member = (new MemberModel())->where(['id' => $member_id])->find();
            if (!$member) {
                return $this->api_error('您还没有登陆～');
            }

            //查询套餐分类
            $packageCate = (new CompanyCateModel())->where(['id' => $package['company_cate_id'], 'status' => 1])->find(
            );
            if (!$packageCate) {
                return $this->api_error('套餐分类不存在');
            }

            $area = explode(',', $company_area_sepc['area_ids']);
            if (in_array($area_name, $area)) {
                $price = $company_area_sepc['price'];
            } else {
                $spec = array_column(json_decode($package['spec'], true), 'price', 'spec_id');
                $price = $spec[$spec_id];
            }
            $amount = $price;
            $out_trade_no = $this->build_order_no("PACKAGE");

            $spec = (new CompanySpecModel())->where(['id' => $spec_id])->find();
            if (!$spec) {
                return $this->api_error('套餐规格不存在');
            }
            if ($price <= 0) {
                $expire_time = (new PayCall())->createDay($spec['type'], $spec['nums']);
                $this->createPackageOrder(
                    $package,
                    $price,
                    $member_id,
                    $packageCate,
                    $out_trade_no,
                    $area_name,
                    $spec,
                    $realname,
                    $phone,
                    $notes,
                    $amount,
                    1,
                    $isWmini,
                    $expire_time
                );
                return $this->api_success('下单成功', true);
            }

            $price = $this->userVipPayment($member, $amount);


            if (!$isWmini) {
                //余额支付
                if ($price > $member['wallet']) {
                    return $this->api_error('余额不足');
                }
                try {
                    Db::startTrans();
                    $expire_time = (new PayCall())->createDay($spec['type'], $spec['nums']);

                    $this->createPackageOrder(
                        $package,
                        $price,
                        $member_id,
                        $packageCate,
                        $out_trade_no,
                        $area_name,
                        $spec,
                        $realname,
                        $phone,
                        $notes,
                        $amount,
                        1,
                        $isWmini,
                        $expire_time
                    );
                    //扣除余额
                    (new MemberModel())->where(['id' => $member_id])->setDec('wallet', $price);
                    //添加日志
                    (new VipCardBill())->addBill($member_id, "购买" . $package['name'], 2, $price);
                    //执行分销
                    (new PayCall())->retail($out_trade_no,$member_id,$price,'package');
                    Db::commit();
                    return $this->api_success('下单成功', true);
                } catch (\Exception $e) {
                    Db::rollback();
                    return $this->api_error('下单失败～');
                }
            } else {
                //创建订单
                if (!$this->createPackageOrder(
                    $package,
                    $price,
                    $member_id,
                    $packageCate,
                    $out_trade_no,
                    $area_name,
                    $spec,
                    $realname,
                    $phone,
                    $notes,
                    $amount,
                    0,
                    $isWmini
                )) {
                    return $this->api_error('下单失败');
                }
            }
        } else {
            //再次支付
            $order = (new CompanyOrderModel())->where(['out_trade_no' => $order_id])->find();
            //查询套餐ID
            $package = (new CompanyPackageModel())->where(['id' => $order['package_id'], 'status' => 1])->find();
            if (!$package) {
                return $this->api_error('企业服务套餐不存在');
            }

            $spec = (new CompanySpecModel())->where(['id' => $order['spec_id']])->find();
            if (!$spec) {
                return $this->api_error('套餐规格不存在');
            }
            //获取用户信息
            $member = (new MemberModel())->where(['id' => $order['member_id']])->find();
            if (!$member) {
                return $this->api_error('您还没有登陆～');
            }
            $out_trade_no = $order['out_trade_no'];
            $price = $order['pay_amount'];
        }

        $config = $this->toPay(
            $package['name'] . '-' . $spec['name'],
            $out_trade_no,
            $price,
            'packageCallback',
            $member['openid']
        );
        if ($config) {
            return $this->api_success('获取成功', $config);
        } else {
            return $this->api_error('下单失败');
        }
    }

    //购买商品
    public function PayGoods($params = array())
    {
        $order_id = $params['order_id'] ?? 0;
        $isWmini = $params['is_wmini'] ?? 0;
        if (!$order_id) {
            $goods_id = $params['goods_id'] ?? 0;
            $address_id = $params['address_id'] ?? 0;
            $nums = $params['nums'] ?? 1;
            $member_id = $params['uid'] ?? 1;
            $notes = $params['notes'] ?? '';

            $goods = (new GoodsModel())->where(['id' => $goods_id, 'status' => 1])->find();

            if (!$goods) {
                return $this->api_error('商品不存在');
            }
            if ($goods['residue_stock'] - $nums <= 0) {
                return $this->api_error('库存不足');
            }
            //获取用户信息
            $member = (new MemberModel())->where(['id' => $member_id])->find();
            if (!$member) {
                return $this->api_error('您还没有登陆～');
            }
            //获取商品分类
            $goods_cate = (new GoodsCateModel())->where(['id' => $goods['goods_cate_id']])->find();
            if (!$goods_cate) {
                return $this->api_error('商品不存在');
            }
            //查询地址
            $address = (new UserAddressModel())->where(['id' => $address_id])->find();
            if (!$address) {
                return $this->api_error('地址不存在');
            }
            $out_trade_no = $this->build_order_no("GS");
            $amount = $nums * $goods['price'];
            $pay_amount = $this->userVipPayment($member, $amount);
            try {
                Db::startTrans();
                if (!$isWmini) {
                    if ($amount > $member['wallet']) {
                        return $this->api_error('余额不足');
                    }
                    //创建订单
                    $this->createGoodsOrder(
                        $goods,
                        $address,
                        $member_id,
                        $nums,
                        $notes,
                        $out_trade_no,
                        $goods_cate,
                        $amount,
                        $pay_amount,
                        $isWmini,
                        1
                    );
                    //扣除余额
                    (new MemberModel())->where(['id' => $member_id])->setDec('wallet', $pay_amount);
                    //添加日志
                    (new VipCardBill())->addBill($member_id, "购买" . $goods['title'], 2, $pay_amount);
                    //执行分销
                    (new PayCall())->retail($out_trade_no,$member_id,$pay_amount,'goods');
                } else {
                    //创建订单
                    $this->createGoodsOrder(
                        $goods,
                        $address,
                        $member_id,
                        $nums,
                        $notes,
                        $out_trade_no,
                        $goods_cate,
                        $amount,
                        $pay_amount,
                        $isWmini,
                        0
                    );
                }

                //减少库存
                (new GoodsModel())->where(['id' => $goods_id])->setDec('residue_stock');
                Db::commit();
                if (!$isWmini) {
                    return $this->api_success('下单成功', true);
                }
            } catch (\Exception $e) {
                Db::rollback();
                return $this->api_error('下单失败');
            }
        } else {
            $order = (new GoodsOrderModel())->where(['out_trade_no' => $order_id])->find();
            $goods = (new GoodsModel())->where(['id' => $order['goods_id'], 'status' => 1])->find();
            if (!$goods) {
                return $this->api_error('商品不存在');
            }
            if ($goods['residue_stock'] - $order['nums'] <= 0) {
                return $this->api_error('库存不足');
            }
            //获取用户信息
            $member = (new MemberModel())->where(['id' => $order['member_id']])->find();
            if (!$member) {
                return $this->api_error('您还没有登陆～');
            }
            $out_trade_no = $order['out_trade_no'];
            $pay_amount = $order['pay_amount'];
        }

        $config = $this->toPay($goods['title'], $out_trade_no, $pay_amount, 'goodsCallback', $member['openid']);
        if ($config) {
            return $this->api_success('获取成功', $config);
        } else {
            return $this->api_error('下单失败');
        }
    }

    //购买财税顾问
    public function payAdvise($params = array())
    {
        $area_name = $params['area_name'] ?? '';
        $handler_id = $params['handler_id'] ?? 0;
        $member_id = $params['uid'] ?? 1;


        //用户信息
        $member = (new MemberModel())->where(['id' => $member_id])->find();
        if (!$member) {
            return $this->api_error('您还没有登陆～');
        }
        //查询财税顾问的信息
        $handler = (new HandlerModel())->where(['id' => $handler_id, 'status' => 1])->find();
        if (!$handler) {
            return $this->api_error('数据不存在');
        }
        if ($handler['level'] == $member['advise_level']) {
            return $this->api_error('您已开通过了～');
        }
        if ($handler['level'] < $member['advise_level']) {
            return $this->api_error('您的等级大于该等级，暂不能开通');
        }

        $amount = $handler['price'];
        $area_price = (new HandlerPrice())->where(['area_name' => $area_name, 'handler_id' => $handler_id])->find();
        if ($area_price) {
            $amount = $area_price['price'];
        }
        $out_trade_no = $this->build_order_no("HD");
        //生成订单
        if ($amount <= 0) {
            try {
                Db::startTrans();
//                $this->createHandlerOrder($member, $amount, $handler, $out_trade_no, $area_name, 1);
                //不参与支付
                //生成二维码
                $path = 'pages/login/index?pid=' . $member['id'] . "&type=advise";
                $qrcode = $this->createQrcode($path, 'advise', $member_id);
                (new MemberModel())->where(['id' => $member_id])->update(
                    ['advise_level' => $handler['level'], 'advise_qrcode' => $qrcode]
                );
                Db::commit();
                return $this->api_success("下单成功", true);
            } catch (\Exception $e) {
                Db::rollback();
                return $this->api_error('下单失败');
            }
        } else {
            $this->createHandlerOrder($member, $amount, $handler, $out_trade_no, $area_name);
        }
        //走支付
        $config = $this->toPay(
            "财税顾问" . $handler['tag'],
            $out_trade_no,
            $amount,
            'handlerCallback',
            $member['openid']
        );
        if ($config) {
            return $this->api_success('获取成功', $config);
        } else {
            return $this->api_error('下单失败');
        }
    }


    public function payVip($params = array())
    {
        $vip_id = $params['vip_id'];
        $member_id = $params['uid'] ?? 35;

        //用户信息
        $member = (new MemberModel())->where(['id' => $member_id])->find();
        if (!$member) {
            return $this->api_error('您还没有登陆～');
        }
        //查询vip的信息
        $vip = (new VipCard())->where(['id' => $vip_id, 'status' => 1])->find();
        if (!$vip) {
            return $this->api_error('数据不存在');
        }

        $pay_amount = $vip['price'];
        if ($member['vip_type'] && $member['vip_expire_time'] > time()) {
            //计算价格
            $userVip = (new VipCard())->where(['id' => $member['vip_type']])->find();
            if ($userVip['level'] > $vip['level']) {
                return $this->api_error('当前会员等级不允许开通本会员');
            }
            if ($member['wallet'] > $vip['price']) {
                $expire_time = (new PayCall())->createDay($vip['expire_type'], $vip['nums']);
                (new MemberModel())->where(['id' => $member_id])->update(
                    ['vip_type' => $vip_id, 'vip_expire_time' => $expire_time]
                );
                return $this->api_success('支付成功', true);
            }
            //续费
            $pay_amount = round($vip['price'] - $member['wallet'], 2);
        }

        $out_trade_no = $this->build_order_no("VIP");
        if (!$this->createVipOrder($vip, $pay_amount, $member, $out_trade_no)) {
            return $this->api_error('下单失败');
        }

        //走支付
        $config = $this->toPay($vip['name'], $out_trade_no, $pay_amount, 'vipCallback', $member['openid']);
        if ($config) {
            return $this->api_success('获取成功', $config);
        } else {
            return $this->api_error('下单失败');
        }
    }


    public function createVipOrder($vip, $pay_amount, $member, $out_trade_no)
    {
        $model = new VipOrderModel();
        $model->out_trade_no = $out_trade_no;
        $model->area_name = '';
        $model->member_id = $member['id'];
        $model->vip_name = $vip['name'];
        $model->vip_cate_name = $this->vip_group[$vip['vip_cate']];
        $model->vip_type = $this->vip_type[$vip['expire_type']];
        $model->vip_nums = $vip['nums'];
        $model->pay_amount = $pay_amount;
        $model->vip_id = $vip['id'];

        if (!$model->save()) {
            return false;
        }
        return true;
    }


    public function createQrcode($path, $type, $member_id)
    {
        $app = Factory::miniProgram(config('wechat.xcx'));
        $response = $app->app_code->getQrCode($path);
        if ($response instanceof \EasyWeChat\Kernel\Http\StreamResponse) {
            $filename = $response->saveAs('uploads/qrcode/', $type . '-' . $member_id . ".png");
        }
        $qrcode = '/uploads/qrcode/' . $filename;
        return $qrcode;
    }


    public function toPay($body, $out_trade_no, $pay_amount, $callback, $openid)
    {
//        $pay_amount = 0.1;
        $app = Factory::payment(config('wechat.wechat_pay'));
        $jssdk = $app->jssdk;
        $data = [
            'body' => $body,
            'out_trade_no' => $out_trade_no,
            'total_fee' => $pay_amount * 100,
            'notify_url' => config('app.image_url') . '/api/pay_call/' . $callback, // 支付结果通知网址，如果不设置则会使用配置里的默认地址
            'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
            'openid' => $openid, //
        ];
        $result = $app->order->unify($data);
        if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {
            $config = $jssdk->sdkConfig($result['prepay_id']); // 返回数组
            if (isset($config['timestamp'])) { // 检查timestamp是否存在
                $config['timeStamp'] = $config['timestamp']; // 复制timestamp的值到timeStamp
                unset($config['timestamp']); // 删除timestamp键
            }
            return $config;
        } else {
            return false;
        }
    }


    public function createHandlerOrder($member, $amount, $handler, $out_trade_no, $area_name, $status = 0)
    {
        $model = (new HandlerOrderModel());

        $model->member_id = $member['id'];
        $model->area_name = $area_name;
        $model->out_trade_no = $out_trade_no;
        $model->handler_id = $handler['id'];
        $model->handler_tags = $handler['tag'];
        $model->price = $amount;
        $model->status = $status;
        if ($status == 1) {
            $model->pay_time = time();
        }

        if (!$model->save()) {
            return false;
        }
        return true;
    }


    public function createGoodsOrder($goods, $address, $member_id, $nums, $notes, $out_trade_no, $goods_cate, $amount, $pay_amount, $pay_type, $status = 0) {
        $goodsModel = new GoodsOrderModel();
        $goodsModel->member_id = $member_id;
        $goodsModel->out_trade_no = $out_trade_no;
        $goodsModel->goods_id = $goods['id'];
        $goodsModel->goods_name = $goods['title'];
        $goodsModel->goods_image = $goods['image'];
        $goodsModel->goods_price = $goods['price'];
        $goodsModel->pay_amount = $pay_amount;
        $goodsModel->goods_cate_id = $goods_cate['id'];
        $goodsModel->goods_cate_name = $goods_cate['name'];
        $goodsModel->phone = $address['phone'];
        $goodsModel->nums = $nums;
        $goodsModel->realname = $address['real_name'];
        $goodsModel->address = $address['region'] . $address['address'];
        $goodsModel->create_time = time();
        $goodsModel->notes = $notes;
        $goodsModel->status = $status;
        $goodsModel->amount = $amount;
        $goodsModel->pay_type = $pay_type;
        if($pay_type == 0){
            $goodsModel->pay_time = time();
        }

        if (!$goodsModel->save()) {
            return false;
        }
        return true;
    }


    public function createPackageOrder(
        $package,
        $price,
        $member_id,
        $packageCate,
        $out_trade_no,
        $area_name,
        $spec,
        $realname,
        $phone,
        $notes,
        $amount,
        $status = 0,
        $pay_type,
        $expire_time = ''
    ) {
        //查询规格
//        $expire_time = $this->createDay($spec['type'], $spec['nums']);
        $packageModel = (new CompanyOrderModel());
        $packageModel->out_trade_no = $out_trade_no;
        $packageModel->member_id = $member_id;
        $packageModel->area_name = $area_name;
        $packageModel->company_package_name = $package['name'];
        $packageModel->company_cate_name = $packageCate['name'];
        $packageModel->spec_name = $spec['name'];
        $packageModel->pay_amount = $price;
        $packageModel->amount = $amount;
        $packageModel->pay_type = $pay_type;
        $packageModel->phone = $phone;
        $packageModel->realname = $realname;
        $packageModel->notes = $notes;
        $packageModel->create_time = time();
        $packageModel->expire_time = $expire_time;
        $packageModel->company_content = $package['content'];
        $packageModel->unit = $package['unit'];
        $packageModel->company_image = $package['image'];
        $packageModel->company_type_name = $package['type_name'];

        $packageModel->package_id = $package['id'];
        $packageModel->status = $status;
        $packageModel->company_cate_id = $packageCate['id'];
        $packageModel->spec_id = $spec['id'];
        if($pay_type == 0){
            $packageModel->pay_time = time();
        }

        if (!$packageModel->save()) {
            return false;
        }
        return true;
    }


    public function createSpecialOrder(
        $special,
        $pay_amount,
        $amount,
        $member,
        $specialCate,
        $out_trade_no,
        $area_name,
        $pay_type,
        $status = 0
    ) {
        //查询订单是否存在
        $order = (new SpecialOrder())->where(['out_trade_no' => $out_trade_no])->count();
        if ($order) {
            return false;
        }

        $specialOrder = (new SpecialOrder());
        $specialOrder->out_trade_no = $out_trade_no;
        $specialOrder->member_id = $member['id'];
        $specialOrder->area_name = $area_name;
        $specialOrder->special_cate_name = $specialCate['name'];
        $specialOrder->title = $special['name'];
        $specialOrder->amount = $amount;
        $specialOrder->pay_amount = $pay_amount;
        $specialOrder->special_id = $special['id'];
        $specialOrder->special_cate_id = $specialCate['id'];
        $specialOrder->phone = $member['phone'];
        $specialOrder->unit = $special['unit'];
        $specialOrder->pay_type = $pay_type;
        $specialOrder->status = $status;

        if($pay_type == 0){
            $specialOrder->pay_time = time();
        }
        if (!$specialOrder->save()) {
            return false;
        }
        return true;
    }


    //生成订单
    public function build_order_no($prefix)
    {
        return $prefix . date('ymd') . substr(
                implode(null, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))),
                0,
                8
            );
    }

}
